package com.ytf.dogbox.inteflyCamera;


import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.SurfaceTexture;
import android.graphics.Typeface;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.ytf.dogbox.R;
import com.ytf.dogbox.activity.FlyUtil;
import com.ytf.dogbox.activity.SocketService;
import com.ytf.dogbox.db.SqliteManager;
import com.ytf.dogbox.fragment.CameraFragment;
import com.ytf.dogbox.listener.ICameraListener;
import com.ytf.dogbox.qiniu.QiNiuUtil;
import com.ytf.dogbox.receive.AlarmReciever;
import com.ytf.dogbox.util.AlarmUtil;
import com.ytf.dogbox.util.BitmapUtil;
import com.ytf.dogbox.util.FileSortUtil;
import com.ytf.dogbox.util.Log;
import com.ytf.dogbox.util.Md5Utils;
import com.ytf.dogbox.util.NV21ToBitmap;
import com.ytf.dogbox.util.PreferenceUtil;
import com.ytf.dogbox.util.TestConfig;
import com.ytf.dogbox.util.TimeUtil;
import com.ytf.dogbox.util.UploadConfig;


import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


import wseemann.media.FFmpegMediaMetadataRetriever;

/**
 * @author tiwolf_li
 * @Date on 2021/8/11
 * @Description 自家摄像头的碎片，用于切割部分画面,视频，图片生产，保存，识别
 */
public class InteflyCameraFragment extends CameraFragment {

    private String TAG= InteflyCameraFragment.class.getSimpleName();

    Context context;

    private InteflyCameraView myOpenGLView;

    private SqliteManager sqliteManager;

    NV21ToBitmap nv21ToBitmap;



    private String showUrl= TestConfig.rkUrl;
    private int picwidth=640;

    RtspRunnable rtspRunnable=new RtspRunnable();

    /**
     * 获取途径为/storage/emulated/0/solar/20191226/camera/20191226102205.mp4
     */
    private String fileName="";
    private String mp4Name="";
    private int imgIndex=0;
    private long mp4Minute=0;
    private String sdPath;
    private boolean isUploadRecord=false;
    private String mp4FilePath;
    String publishStr;
    private byte[] nv21Face=null;//这个用来做封面
    private Bitmap bitFace=null;
    private int nv21Width;
    private int nv21height;
    private boolean nv21Flag=false;//获取封面的标志
    boolean isHasPic=false;
    boolean pictureFlag=false;
    boolean pictureIsChangeFlag=false;
    boolean policePictureFlag=false;
    int pictureInt=1;
    int movePicturInt=30;
    int invalitInt=0;
    int lastPersonNum=-1;
    int total=0;
    int lastDay=1;
    int lastTotal=0;
    int i=0;
    int lastCameraInt=0;
    int isCameraInt=0;
    Date d2=null;
    File fileFolder;
    boolean onePictureFlag=true;
    int iswelcomeInt=200;

    int picSize=0;
    byte[] nv21cp;

    int recordMin=1;
    //添加一个判断标志，以免出现多次录制
    boolean doRecord=true;


    boolean cameraDo=true;
    boolean isOnNet=false;
    private boolean isCameraBl=true;

    boolean isSaveFileFlag=true;
    private boolean peopleDo=false;
    boolean hasStopLive=false;

    ContentValues contentValues=new ContentValues();

    ContentValues contentValues1=new ContentValues();
    Thread picThread=null;
    private static Object picObject=new Object();
    private ConcurrentLinkedDeque<String> cacheLinkedDequePic = new ConcurrentLinkedDeque<>();



    public InteflyCameraFragment(){}


    //直接从activity获取语言，屏幕

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        this.context=context;
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        View rootView=inflater.inflate(R.layout.fragment_intefly,container,false);
        myOpenGLView=rootView.findViewById(R.id.openglView);
        nv21ToBitmap=new NV21ToBitmap(context);

        sdPath= FileSortUtil.getStoragePath(context,true);
        Log.i(TAG, "onCreateView: 我司摄像头路径是==="+sdPath );
        FileSortUtil.createAppPath(sdPath);
        myOpenGLView.setBitmapSize(640,480);
        myOpenGLView.setBitmapCodecUtil();
        myOpenGLView.initAudio();



        Log.e(TAG, "onCreateView: 创建了texttureview布局11="+myOpenGLView );
        myOpenGLView.showBitmap(new InteflyCameraView.IShowPicture() {
            @Override
            public void showData(byte[] nv21, int height, int width) {
                //每个视频在没有警报情况下，最多不超过5张图片,不限制图片。一下子就会一大堆
                //解决下面大坑，限制法
                long l = System.currentTimeMillis();


                if (onePictureFlag && iCameraListener!=null){
                    onePictureFlag=false;
                    iCameraListener.isHasPic(true);
                }


                if (nv21Flag){

                    nv21Flag=false;
                    //保存一张图片
                    nv21Face=nv21;
                    nv21Width=width;
                    nv21height=height;
                    Log.i(TAG, "showData: 人脸识别之提取一张图片的时间="+(System.currentTimeMillis()-l) );
                }else if (policePictureFlag){  //取消取图数量限制
                    //这个是报警  这种情况是在人脸识别没有激活的情况下
                    policePictureFlag=false;
                    Log.i(TAG, "showData: 人脸识别 报警创建文件333399999" );
                    createPic(nv21, height,width);
                }
            }

            @Override
            public void cameraIsWorking() {

                isCameraInt++;
//                Log.i(TAG, "cameraIsWorking: "+isCameraInt );
            }

            @Override
            public void isCameraLink(long flag) {
                //如果登录不成功，则过几秒再连接摄像头

            }

            @Override
            public void showLog(String log) {
                Log.i(TAG, "showLog: 迈特推流日志："+log );
            }

            @Override
            public void picIsMove() {
                //发生移动侦测
                Log.i(TAG, "picIsMove:人脸识别 发生侦测移动==============发生侦测" );
                pictureIsChangeFlag=true;

            }

        });
        try {
            myOpenGLView.setStartStream();
        }catch (Exception e){
            e.printStackTrace();
        }
        Log.e(TAG, "onCreateView: 开始拉流" );
        new Thread(rtspRunnable).start();
        picThread=new Thread(new Runnable() {
            @Override
            public void run() {
                while (!Thread.interrupted()) {
                    while (!cacheLinkedDequePic.isEmpty()) {
                        String msg = cacheLinkedDequePic.poll();
                        try {
                            handlerPictureCreate(msg);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }

                    //Waiting for next file
                    synchronized (picObject) {
                        try {
                            //isEmpty() may take some time,so we set timeout to detect next file
                            picObject.wait(1000);
                        } catch (InterruptedException e) {
//                        e.printStackTrace();
                            picThread.interrupt();
                        }
                    }

                }


            }
        });
        picThread.start();
        watchRecordDogUtil();
        return rootView;
    }

    public boolean dogFlag=true;
    public boolean mp4CreateFlag=false;
    public int dogInt=80;
    //用来监测设备是否录制多过一分钟
    public void watchRecordDogUtil(){

        new Thread(new Runnable() {
            @Override
            public void run() {
                dogInt=recordMin*60+2;
                while (dogFlag){
                    if (mp4CreateFlag){
                        dogInt--;
                        if (dogInt<0){
                            //说明一分钟过去了定时还没好，开始主动结束。然后重新开始
                            Log.i(TAG, "run: 监测到一分钟过去了还未定时结束，强制结束。然后重新开始");
                            startRecordMp4();
                        }else if (dogInt<10){
                            iCameraListener.isCanCreateRecord(true);
                        }
//                        Log.i(TAG, "run: 监测到录制，当前数值为="+dogInt);
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }

                }
            }
        }).start();

    }


    private void handlerPictureCreate(String picFilePath){
        //TODO 在这里进行上传视频生成的时间（文件名），sn
        //休眠一秒钟来确保文件已经保存好
        //对文件大小进行判断，如果大于一兆才会保存及上传
        File file=new File(picFilePath);
        Log.e(TAG, "startRecordMp4: mp4录制停止后准备获取图片"+picFilePath+";file="+file.exists()+";file-length="+file.length());
        File file1=null;
        if(file.exists() && file.length()>512*1024){
            long start=System.currentTimeMillis();
            Log.i(TAG, "receiveWork: 在这里完成了一帧图片的提取="+mp4Name+",图片111"+";");
            if (bitFace!=null){
                if (bitFace==null){
                    Log.i(TAG, "receiveWork: 图片未能获取成功" );
                }else {
                    file1= BitmapUtil.saveToSDCard1(sdPath,BitmapUtil.bitmabToBytes(bitFace,60),fileName,mp4Name);
                    if (file1==null){
                        iCameraListener.setError(1);
                        Log.i(TAG, "createPic: 创建文件出现问题，tfcard有问题" );
                    }else{
                        iCameraListener.setError(0);
                    }
                }

            }else{
                //如果没有这个，只能从前一个视频里面获取最后一帧图片
                Log.i(TAG, "startRecordMp4: 没有拿到帧图片的时候，只能直接提取="+picFilePath );
                if (picFilePath!=null){
                    try {
                        Bitmap bitmap=getVideoThumb(picFilePath,100000);
//                                Bitmap bitmap=getVideoThumbnail(picFilePath,640,480);
                        Log.i(TAG, "startRecordMp4: 没有拿到帧图片的时候，只能直接提取00="+bitmap );
                        file1= BitmapUtil.saveToSDCard1(sdPath,BitmapUtil.bitmabToBytes(bitmap,60),fileName,mp4Name);
                        if (file1==null){
                            iCameraListener.setError(1);
                            Log.i(TAG, "createPic: 创建文件出现问题，tfcard有问题" );
                        }else{
                            iCameraListener.setError(0);
                        }
//                        if (bitmap!=null){
//                            bitmap.recycle();
//                            bitmap=null;
//                        }
                    }catch (Exception e){
                        e.printStackTrace();
                        Log.i(TAG, "startRecordMp4:没有拿到帧图片的时候，只能直接提取,但是出错了="+e.getLocalizedMessage() );
                    }

                }


            }



            Log.i(TAG, "receiveWork: 在这里完成了一帧图片的提取，请进去查看"+mp4Name+",图片"+bitFace );
            if (file1!=null){

                iCameraListener.setRecordPicture(mp4Name);

                //将图片记录到本地服务器
                contentValues1.clear();
                contentValues1.put(UploadConfig.fileName,file1.getName());
                contentValues1.put(UploadConfig.ext,"jpg");
                contentValues1.put(UploadConfig.name,mp4Name);
                contentValues1.put(UploadConfig.filePath,file1.getAbsolutePath());
                sqliteManager.savePicItem(contentValues1);
            }



            Log.i(TAG, "receiveWork: 一套图片下来所需时间:"+(System.currentTimeMillis()-start));
        }
    }

    private ArrayList<BitmapBean> frameList = new ArrayList<>();
    private void handlerPicture(BitmapBean bitmapBean){


    }

    boolean isFirstFlag=true;
    private ArrayList<Bitmap> bitmaps=new ArrayList<>();
    private void handlerBitmap(Bitmap bitmap){

    }

    @Override
    public void onDestroyView() {
        cameraDo=false;
        dogFlag=false;
        if (picThread!=null){
            picThread.interrupt();
            try {
                picThread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
                picThread.interrupt();
            }
            picThread=null;
        }
        stopRtmpPublish();
        endRecord();
        destroyCamera();
        super.onDestroyView();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    String lastMp4Path;
    private synchronized void createPic(Bitmap bitmap){
        //图片生成的时间
        Date date = new Date();
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss"); // 格式化时间
        String imageCreate = format.format(date);
        File file=null;
        if (sdPath==null || sdPath.length()==0){
            if (bitmap!=null){
                bitmap.recycle();
                bitmap=null;
            }
            return;
        }
        file= BitmapUtil.saveToSDCard1(sdPath,BitmapUtil.bitmabToBytes(bitmap,100),fileName,mp4Name,"A",imgIndex);

        imgIndex++;
        isSaveFileFlag=true;

        if (file!=null){
            Log.i(TAG, "showData: 人脸识别:,owner="+ FlyUtil.getSn(context)+",originName="+file.getName()+",filePath="+file.getAbsolutePath()+",ext=jpg,lastModifiedTime="+imageCreate+",size="+file.length() );
            saveFileToSql(file,imageCreate,date,"jpg",1);

        }else if (peopleDo){
            peopleDo=false;
            iCameraListener.setPeopleDo(false);
            SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 格式化时间
            String timeStr = format1.format(date);
            if (iCameraListener!=null)
                iCameraListener.setPictureParams(null,timeStr,1);//这个是一键报警的
//                policeMap=new ArrayMap<>();
//                policeMap.put("alarmTime",timeStr);
//                policeMap.put("pictureMd5",null);
//                policeMap.put("sn",SocketService.CLIENTID);
//                handler.sendEmptyMessage(POLICEPITUREUPDATE);
//                    policePictureFlag=false;
        }
    }

    private synchronized void createPic(byte[] nv21, int height, int width) {
        //图片生成的时间
        Date date = new Date();
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss"); // 格式化时间
        String imageCreate = format.format(date);
        if (mp4Name!=null){

            //进行时间对比，如果当前时间大于图片时间3分钟。则重新开启一个mp4.因为这个mp4录制已经有问题了
            if (date.getTime()-mp4Minute>((recordMin+1)*60*1000)){
                //如果时间戳和上一个视频的创建时间大于规定时间，那么说明当前没有进行mp4创建。则重新创建mp4
                Log.i(TAG, "showData: 人脸识别 进行了一次mp4创建" );
                isCameraBl=true; //主要是这个报警和移动侦测都有几秒，不然不能使用（使用这个有风险）
            }

            File file=null;
            //图片不会再写进来
            if (sdPath==null || sdPath.length()==0){
                nv21=null;
                return;
            }else {
                Bitmap bitmap=nv21ToBitmap.nv21ToBitmap(nv21,width,height);
                file= BitmapUtil.saveToSDCard1(sdPath,BitmapUtil.bitmabToBytes(bitmap,100),fileName,mp4Name,"A",imgIndex);
            }

            imgIndex++;
            isSaveFileFlag=true;

            if (file!=null){
                Log.i(TAG, "showData: 人脸识别:,owner="+ FlyUtil.getSn(getContext()) +",originName="+file.getName()+",filePath="+file.getAbsolutePath()+",ext=jpg,lastModifiedTime="+imageCreate+",size="+file.length() );
                saveFileToSql(file,imageCreate,date,"jpg",1);

            }else if (peopleDo){
                peopleDo=false;
                iCameraListener.setPeopleDo(false);
                SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 格式化时间
                String timeStr = format1.format(date);
                if (iCameraListener!=null)
                    iCameraListener.setPictureParams(null,timeStr,1);//这种也属于一键报警的情况
            }


        }
    }

    private void saveFileToSql(File file,String imageCreate,Date date,String ext,int type){
        String md5Str= FlyUtil.getSn(getContext()) +"&"+file.getName()+"&"+ext+"&"+imageCreate+"&"+file.length();
//                        Log.i(TAG, "show: "+file.getName().substring(0,file.getName().length()-4) );
        String md5= Md5Utils.md5Str(md5Str.toLowerCase());
//                ContentValues contentValues=new ContentValues();
        contentValues.clear();
        contentValues.put(UploadConfig.originName,file.getName());
        contentValues.put(UploadConfig.ext,ext);
        contentValues.put(UploadConfig.lastModifiedTime,imageCreate);
        contentValues.put(UploadConfig.filePath,file.getAbsolutePath());
        contentValues.put(UploadConfig.md5,md5);
        contentValues.put(UploadConfig.size,file.length());
        if (peopleDo){
            contentValues.put(UploadConfig.upstate,9);//9表示报警文件,需要马上上传
        }else {
            contentValues.put(UploadConfig.upstate,0);//0表示还未上传
        }
        if (sqliteManager!=null)
            sqliteManager.saveItem(contentValues);

        //这句放在这里纯属害人，如果没达到条件，policePictureFlag将一直为true。这样子就会一直产生图片
//                if (policePictureFlag && peopleDo){
        if (peopleDo){
            peopleDo=false;
            iCameraListener.setPeopleDo(false);
            SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 格式化时间
            String timeStr = format1.format(date);
            if (iCameraListener!=null)
                iCameraListener.setPictureParams(md5,timeStr,type);
        }
    }

    //TODO 2021-02-20 使用isPictureDo来降低因为MaiteOpenGLView启动两次导致的图片问题
    String iswelcomeMode="1";
    private boolean isQiniuFlag=false;  //是否创建了七牛云

    ICameraListener iCameraListener;
    public void setCameraListener(ICameraListener iCameraListener){
        this.iCameraListener=iCameraListener;
    }

    /**
     * 按了报警之后
     * @param policePictureFlag  是否可以生成图片
     * @param isPeopleDo 是否是人去按的
     */
    public void setPolicePictureFlag(boolean policePictureFlag,boolean isPeopleDo){
        this.policePictureFlag=policePictureFlag;
        peopleDo=isPeopleDo;

        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        long start=System.currentTimeMillis();
        if (lastMp4Path!=null && this.policePictureFlag){
            //如果100毫秒之后，发现报警标志还是没变false，说明纹理没有数据出来，则在这里进行一个图片获取
            Log.i(TAG, "setPolicePictureFlag: 上一个mp4路径为="+lastMp4Path);
            Bitmap bitmap=getVideoThumb(lastMp4Path,100*1000);
            if (bitmap!=null){
                createPic(bitmap);
            }

            Log.i(TAG, "setPolicePictureFlag: 获取40s的视频路径为" );
        }
    }

    public void createQiniuRoom(){
        isQiniuFlag=PreferenceUtil.getBoolean(PreferenceUtil.QINIUROOM,false);
        if (SocketService.isQiNiuFlag){
            publishStr= QiNiuUtil.getRtmpUrl(isQiniuFlag,TestConfig.accessKey,TestConfig.secretKey,getContext());
        }
    }

    public void stopRtmpStream(){
        //无网络时关闭推流器
        myOpenGLView.stopRtmpPublish();
    }

    public void releaseCamera(){
        cameraDo=false;
        myOpenGLView.stopStream();
    }

    public void destroyCamera(){
        releaseCamera();
        //关闭摄像头，打开热点或其他
        myOpenGLView.destroy();
    }

    public int rebootCamera(int code,String user,String passwd,String ip){
        return myOpenGLView.rebootCamera(code, user, passwd, ip);
    }

    public void endRecord(){
        myOpenGLView.endRecord();
    }

    public int startQiPlayBack(String path,String url){
        return myOpenGLView.startQiPlayBack(path,url);
    }

    public int isEnd(int handle){
        return myOpenGLView.isEnd(handle);
    }

    public int stopPlayBack(String path,int handle){
        return myOpenGLView.stopPlayBack(path,handle);
    }

    public void restartAudio(){
        myOpenGLView.restartAudio();
    }

    public void stopRecord(){
        myOpenGLView.stopRecord();
    }

    public void startRtmpPublisher(boolean stopRtmpFlag){
        myOpenGLView.startRtmpPublisher(stopRtmpFlag);
    }

    public void startRtmpPublisher(boolean stopRtmpFlag,String url){
        myOpenGLView.startRtmpPublisher(stopRtmpFlag,url);
    }

    public void stopRtmpPublish(){
        myOpenGLView.stopRtmpPublish();
    }

    public void stopRtmpPublisher(String url){
        myOpenGLView.stopRtmpPublisher(url);
    }

    private int login(int x, String user, String passwd, String ip){
        return myOpenGLView.login(x, user, passwd, ip);
    }

    public int ptzRight(int itfi, String usrname, String pwd, String ip){
        return myOpenGLView.ptzRight(itfi, usrname, pwd, ip);
    }

    private int ptzLeft(int itfi, String usrname, String pwd, String ip){
        return myOpenGLView.ptzLeft(itfi, usrname, pwd, ip);
    }

    public int ptzStop(int itfi, String usrname, String pwd, String ip){
        return myOpenGLView.ptzStop(itfi, usrname, pwd, ip);
    }

    private int ptzUp(int itfi, String usrname,String pwd,String ip){
        return myOpenGLView.ptzUp(itfi, usrname, pwd, ip);
    }

    private int ptzDown(int itfi, String usrname,String pwd,String ip){
        return myOpenGLView.ptzDown(itfi, usrname, pwd, ip);
    }

    private int zoomOut(int itfi, String usrname,String pwd,String ip){
        return myOpenGLView.zoomOut(itfi, usrname, pwd, ip);
    }

    private int zoomIn(int itfi, String usrname,String pwd,String ip){
        return myOpenGLView.zoomIn(itfi, usrname, pwd, ip);
    }
    public void setFragmentParams(SqliteManager sqliteManager){
        this.sqliteManager=sqliteManager;
    }

    //设置人脸识别后的模式
    public void setFaceDistinguish(String mode){

    }

    public void setNetworkFlag(boolean isOnNetWork){
        this.isOnNet=isOnNetWork;
        if (myOpenGLView!=null){
            myOpenGLView.getNetWork(isOnNetWork);
        }
    }

    int openviewWidth,openviewHeight;
    //这个是设置人脸描绘

    boolean isNeedPoliceFlag=false;//原先用来做是否需要报警判断，现在也是判定单独识别到汽车后是否需要图片
    boolean alarmFlag=false;//闹钟进来即做标记，相当于每分钟报警一次



    private class RtspRunnable implements Runnable {

        @Override
        public void run() {
            while(cameraDo){


                //摄像头部分-5
                if (myOpenGLView!=null){
//                    Log.i(TAG, "run: 开始获取h264流" );
                    myOpenGLView.startGetH264(showUrl);
                }
//                Log.i(TAG, "run: 开始获取h264流11" );
                //有画面之后再开始激活
//                Log.i(TAG, "run: engine 激活与否"+isEngineFlag+";当前值"+engineInt+";网络"+isOnNet );



                //如果没有流，那么会出现下一次。lastCameraInt和isCameraInt一样的情况.
                //主要用来判断是否还有图片出来 以用来进行mp4录制
                Log.i(TAG, "run: 摄像头现在："+isCameraInt+";之前:"+lastCameraInt+";最后得到"+Math.abs(isCameraInt-lastCameraInt)+";isCameraBl="+isCameraBl );
                if(Math.abs(isCameraInt-lastCameraInt)>0){
                    lastCameraInt=isCameraInt;
                    if (isCameraInt>10000){
                        isCameraInt=0;
                    }


                    if (isCameraBl){
                        isCameraBl=false;
                        setPublishRecord();
                        Log.i(TAG, "mp4Worker run: mp4的创建3333" );

                    }
//                Log.i(TAG, "摄像头:有流 " );
                }else {
                    lastCameraInt=0;
                    isCameraInt=0;
                    Log.i(TAG, "mp4Worker 摄像头:没有流,图片出来了" );
                    if (!isCameraBl){
                        isCameraBl=true;
                        //停止录制  取消定时闹钟
//                    myOpenGLView.stop();
                        myOpenGLView.endRecord();
                        //停止推流
                        myOpenGLView.stopRtmpPublisher();
                    }

                }


                try {
                    Thread.sleep(10*1000);//增大秒数来确保网线一定是断开了
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            cameraDo=true;
        }
    }


    /**
     * 设置摄像头的分辨率和拉流地址
     * @param width
     * @param height
     * @param url
     */
    public synchronized void setCamera(int width,int height,String url){
        if (!cameraDo){
            cameraDo=true;
        }else {
            cameraDo=false;
        }
        myOpenGLView.stopStream();
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Log.i("TAG", "onClick: 上个线程结束，开始跑码流"+cameraDo+";地址为="+url);
        if (cameraDo){

            myOpenGLView.setStartStream();
            myOpenGLView.setCameraSize(width,height);
            showUrl=url;
            new Thread(rtspRunnable).start();
        }

    }



    //添加一个判断标志，以免出现多次录制
    private synchronized void setPublishRecord(){
        Log.i(TAG, "setPublishRecord: doRecord标志为"+doRecord );
        if (doRecord){
            doRecord=false;
            //这个是停止mp4编码

//            myOpenGLView.stop();
            myOpenGLView.endRecord();
//            d2=new Date();
//            createNewRecord(d2,recordMin);
            isSaveFileFlag=false;
            hasStopLive=false;
            doRecord=true;

            //todo 2021.8.14 周一继续，这个是录制视频部分
            startRecordMp4();
        }

    }

    public synchronized void startRecordMp4(){
        //应该先取消之前的闹钟
//        AlarmUtil.cancelAlarm(-100,context);
        // 已经开始录制后，在短时间内，不可以重复创建
        iCameraListener.isCanCreateRecord(false);
        alarmFlag=true;
        /**
         * 定时视频进行处理
         */
        //过了3分钟关闭
//                myOpenGLView.stop();
//                Log.i(TAG, "receiveWork: mp4的创建来了"+sdPath );
        //避免写到手机存储里面，导致异常
        if (sdPath!=null && sdPath.length()>0){
            try {
                myOpenGLView.endRecord();
                dogInt=recordMin*60+2;
                Log.i(TAG, "startRecordMp4: 监测录制完成，重新开始计时为="+dogInt);
            }catch (Exception e){
                Log.e(TAG, "startRecordMp4: mp4停止录制的时候出现问题="+e.getLocalizedMessage());
            }

            Log.e(TAG, "startRecordMp4: mp4停止录制后开始");
            if (mp4Name!=null && mp4Name.length()>6 && "2017".equals(mp4Name.substring(0,4))){
                //如果文件名是2013的文件，我们就不要了
                Log.e(TAG, "startRecordMp4: mp4录制停止后删除文件");
                delRecord(d2);
            }else if(mp4FilePath!=null){
                Log.e(TAG, "startRecordMp4: mp4录制停止后重新开始");
                long recordStart=System.currentTimeMillis();
                //录制完成后，检查是否需要保存的视频，如果是，则上传（当前为识别到人脸和有报警）
                if ((isSaveFileFlag && d2!=null)){
                    Log.e(TAG, "startRecordMp4: mp4录制停止后重新开始==========");
                    saveMp4(d2);
                    long useTime=System.currentTimeMillis()-recordStart;
                    Log.e(TAG, "startRecordMp4: mp4录制保存文件花费的时间为="+useTime);
                }
                Log.e(TAG, "startRecordMp4: mp4录制停止后准备获取图片1111111111111111111111111111111");

                //使用另外的线程进行图片提取，避免对录制造成影响
                cacheLinkedDequePic.add(mp4FilePath);
                synchronized (picObject) {
                    picObject.notifyAll();
                }

            }

            lastMp4Path=mp4FilePath;

            Log.i(TAG, "run: mp4录制-1111，创建文件日期="+hasStopLive );
            if (!hasStopLive){
                Date date=new Date();
                createNewRecord(date,recordMin);
                mp4CreateFlag=true;
                d2=date;
                isSaveFileFlag=false;
                Log.i(TAG, "run: mp4录制=1414，创建和定时全部完成" );
            }
        }

    }

    @Override
    public void setDrawHelper() {

    }

    /**
     * 获取视频文件第一帧图
     *
     * @param path 视频文件的路径
     * @return Bitmap 返回获取的Bitmap
     */
    public static Bitmap getVideoThumb(String path,long time) {
        FFmpegMediaMetadataRetriever fFmpegMediaMetadataRetriever=new FFmpegMediaMetadataRetriever();
        try {
            fFmpegMediaMetadataRetriever.setDataSource(path);
            Bitmap bitmap=fFmpegMediaMetadataRetriever.getFrameAtTime(time,FFmpegMediaMetadataRetriever.OPTION_CLOSEST_SYNC);
            fFmpegMediaMetadataRetriever.release();
            return bitmap;
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }

    }

    boolean cameraoperating=true;
    boolean isStopDo=false;
    public void setCameraOperation(String order,int itfi,String usrname,String pwd,String ip){
        switch (order){
            case "zoomtele":{
                if (cameraoperating){
                    cameraoperating=false;

                    //放大
                    int flag = zoomOut(itfi, usrname, pwd, ip);
                    if (flag!=0){
                        int flag1=login(itfi,usrname,pwd,ip);
                        if (flag1==0){
                            if (iCameraListener!=null)
                                iCameraListener.operationBack(getString(R.string.cameraset));
                            zoomOut(itfi, usrname, pwd, ip);
                            try {
                                Thread.sleep(1000);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            ptzStop(itfi,usrname,pwd,ip);
                        }
                    }else {
                        if (iCameraListener!=null)
                            iCameraListener.operationBack(getString(R.string.cameraset));
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        ptzStop(itfi,usrname,pwd,ip);
                    }
                    cameraoperating=true;

                }

                break;
            }
            case "zoomwide":{
                //缩小
                if (cameraoperating){
                    cameraoperating=false;
                    int flag = zoomIn(itfi, usrname, pwd, ip);
                    if (flag!=0){
                        int flag1=login(itfi,usrname,pwd,ip);
                        if (flag1==0){
                            if (iCameraListener!=null)
                                iCameraListener.operationBack(getString(R.string.cameraset));
                            zoomIn(itfi, usrname, pwd, ip);
                            try {
                                Thread.sleep(1000);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            ptzStop(itfi,usrname,pwd,ip);
                        }
                    }else {
                        if (iCameraListener!=null)
                            iCameraListener.operationBack(getString(R.string.cameraset));
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        ptzStop(itfi,usrname,pwd,ip);
                    }
                    cameraoperating=true;
                }
                break;
            }
            case "up": {
                //向上
                if (cameraoperating){
                    cameraoperating=false;
                    int flag = ptzUp(itfi, usrname, pwd, ip);
                    if (flag != 0) {
                        int flag1 = login(itfi, usrname, pwd, ip);
                        if (flag1 == 0) {
                            if (iCameraListener!=null)
                                iCameraListener.operationBack(getString(R.string.cameraset));
                            ptzUp(itfi, usrname, pwd, ip);
                        }
                    } else {
                        if (iCameraListener!=null)
                            iCameraListener.operationBack(getString(R.string.cameraset));
                    }
                    if (isStopDo){
                        isStopDo=false;
                        Log.i(TAG, "sendMsgToActivity: 摄像头停止操作5555555");
                        ptzStop(itfi, usrname, pwd, ip);
                    }
                    cameraoperating=true;
                }

                break;
            }
            case "down":{
                //向下
//                            myOpenGLView.PtzDown(itfi,usrname,pwd,ip);
                if (cameraoperating){
                    cameraoperating=false;
                    int flag = ptzDown(itfi, usrname, pwd, ip);
                    if (flag!=0){
                        int flag1=login(itfi,usrname,pwd,ip);
                        if (flag1==0){
                            if (iCameraListener!=null)
                                iCameraListener.operationBack(getString(R.string.cameraset));
                            ptzDown(itfi, usrname, pwd, ip);
                        }
                    }else {
                        if (iCameraListener!=null)
                            iCameraListener.operationBack(getString(R.string.cameraset));
                    }
                    if (isStopDo){
                        isStopDo=false;
                        Log.i(TAG, "sendMsgToActivity: 摄像头停止操作5555555");
                        ptzStop(itfi, usrname, pwd, ip);
                    }
                    cameraoperating=true;
                }

                break;
            }
            case "right": {
                //向右
//                            myOpenGLView.PtzRight(itfi,usrname,pwd,ip);
                if (cameraoperating){
                    cameraoperating=false;
                    int flag = ptzRight(itfi, usrname, pwd, ip);
                    if (flag != 0) {
                        int flag1 = login(itfi, usrname, pwd, ip);
                        if (flag1 == 0) {
                            if (iCameraListener!=null)
                                iCameraListener.operationBack(getString(R.string.cameraset));
                            ptzRight(itfi, usrname, pwd, ip);
                        }
                    } else {
                        if (iCameraListener!=null)
                            iCameraListener.operationBack(getString(R.string.cameraset));
                    }
                    if (isStopDo){
                        isStopDo=false;
                        Log.i(TAG, "sendMsgToActivity: 摄像头停止操作5555555");
                        ptzStop(itfi, usrname, pwd, ip);
                    }
                    cameraoperating=true;
                }

                break;
            }
            case "left": {
                //向左
//                            myOpenGLView.PtzLeft(itfi,usrname,pwd,ip);
                if (cameraoperating){
                    cameraoperating=false;
                    int flag = ptzLeft(itfi, usrname, pwd, ip);
                    if (flag != 0) {
                        int flag1 = login(itfi, usrname, pwd, ip);
                        if (flag1 == 0) {
                            if (iCameraListener!=null)
                                iCameraListener.operationBack(getString(R.string.cameraset));
                            ptzLeft(itfi, usrname, pwd, ip);
                        }
                    } else {
                        if (iCameraListener!=null)
                            iCameraListener.operationBack(getString(R.string.cameraset));
                    }
                    if (isStopDo){
                        isStopDo=false;
                        Log.i(TAG, "sendMsgToActivity: 摄像头停止操作5555555");
                        ptzStop(itfi, usrname, pwd, ip);
                    }
                    cameraoperating=true;
                }
                break;
            }
            case "stop":{
                //停止
//              myOpenGLView.PtzStop(itfi,usrname,pwd,ip);
                Log.i(TAG, "sendMsgToActivity:摄像头停止操作 " );
                if (cameraoperating){
                    cameraoperating=false;
                    try {
                        Thread.sleep(50);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    Log.i(TAG, "sendMsgToActivity: 摄像头停止操作11111");
                    int flag = ptzStop(itfi, usrname, pwd, ip);
                    if (flag!=0){
                        Log.i(TAG, "sendMsgToActivity: 摄像头停止操作2222222222");
                        int flag1=login(itfi,usrname,pwd,ip);
                        if (flag1==0){
                            if (iCameraListener!=null)
                                iCameraListener.operationBack(getString(R.string.cameraset));
                            Log.i(TAG, "sendMsgToActivity: 摄像头停止操作333333333333");
                            ptzStop(itfi, usrname, pwd, ip);
                            Log.i(TAG, "sendMsgToActivity: 摄像头停止操作4444444444444");
                        }
                    }else {
                        if (iCameraListener!=null)
                            iCameraListener.operationBack(getString(R.string.cameraset));
                    }
                    cameraoperating=true;
                }else {
                    //TODO 互斥的情况下将标志设置为true，这样子可以在方向指令执行完成的时候判断是否执行stop指令
                    isStopDo=true;
                    Log.i(TAG, "sendMsgToActivity:没有执行stop指令" );
                }
                break;
            }

        }
    }

    @Override
    public void setCameraOperation(String order) {

    }

    /**
     * 设置摄像头分辨率模式
     * @param configCode ="easmooth" 流畅，"hdefinition" 高清，"sclear" 超清  1流畅，2 高清
     */
    @Override
    public void setCameraMode(int configCode) {
        setCamera(640,480,TestConfig.rkUrl);
    }

    @Override
    public int prePoint(int code, String user, String passwd, String ip) {
        Log.i("TAG", "进行了手动聚焦" );
        return myOpenGLView.PrePoint(code,user,passwd,ip);
    }

    @Override
    public int setThirdStreamParam(int code, String user, String passwd, String ip) {
        return myOpenGLView.setThirdStreamParam(code,user,passwd,ip);
    }

    @Override
    public int getThirdStreamParam(int code, String user, String passwd, String ip) {
        return myOpenGLView.getThirdStreamParam(code,user,passwd,ip);
    }

    private void saveMp4(Date date) {
//        Log.i(TAG, "saveMp4: 将其保存到数据库" );
        Log.i(TAG, "saveMp4: 保存mp4文件" );
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss"); // 格式化时间
        String filedir = format.format(date);

//        String filePath=Environment.getExternalStorageDirectory()+"/solar/"+filedir.substring(0,8)+"/camera/"+filedir+".mp4";
        String filePath;
        if (sdPath==null || sdPath.length()==0){
            filePath=Environment.getExternalStorageDirectory()+"/solar/"+filedir.substring(0,8)+"/camera/"+filedir+".mp4";
        }else {
            filePath=sdPath+"/solar/"+filedir.substring(0,8)+"/camera/"+filedir+".mp4";
        }
        File file=new File(filePath);
        if (file.exists() && file.isFile() && file.length()>=1024*1024*0.1){
            Log.i(TAG, "saveMp4: 上传 保存mp4文件1111" );
            //将其记录进去数据库
            String md5Str=FlyUtil.getSn(getContext()) +"&"+file.getName()+"&mp4&"+file.getName().substring(0,file.getName().length()-4)+"&"+file.length();
            Log.i(TAG, "saveMp4: "+md5Str );
            String md5= Md5Utils.md5Str(md5Str.toLowerCase());
//            ContentValues contentValues=new ContentValues();
            contentValues.clear();
            contentValues.put(UploadConfig.originName,file.getName());
            contentValues.put(UploadConfig.ext,"mp4");
            contentValues.put(UploadConfig.lastModifiedTime,file.getName().substring(0,file.getName().length()-4));
            contentValues.put(UploadConfig.filePath,file.getAbsolutePath());
            contentValues.put(UploadConfig.md5,md5);
            contentValues.put(UploadConfig.size,file.length());
            contentValues.put(UploadConfig.upstate,0);//0表示还未上传
            sqliteManager.saveItem(contentValues);

        }else {
            Log.i(TAG, "saveMp4: 上传后，文件太小删除-保存mp4文件2222"+filePath );
            file.delete();
            //视频录制有问题，直接重启看下
//            finish();
        }
    }

    /**
     * 录制视频 获取途径为/storage/emulated/0/solar/20191226/camera/20191226102205.mp4
     * @param d1 时间名字
     * @param min 间隔多少时间录制
     */
    private void createNewRecord(Date d1,int min){
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss"); // 格式化时间
        String filedir = format.format(d1);
        Log.i(TAG, "run: mp4录制-2222，拿到录制时间，准备进行各种文件夹创建.录制时间="+filedir );
        mp4Minute=d1.getTime();
//        Log.i(TAG, "mp4的创建 createNewRecord: 时间为"+filedir+";时间戳为"+mp4Minute );
        fileName=filedir.substring(0,8);
        //生成文件夹
//        fileFolder = new File(Environment.getExternalStorageDirectory() + "/solar/"+filedir.substring(0,8)+"/");
        try {
            if (sdPath==null || sdPath.length()==0){
                fileFolder = new File(Environment.getExternalStorageDirectory() + "/solar/"+filedir.substring(0,8)+"/camera/");
//            Log.i(TAG, "mp4的创建 6666"+fileFolder );
            }else {
                fileFolder = new File(sdPath+ "/solar/"+filedir.substring(0,8)+"/camera/");
                Log.i(TAG, "mp4录制-3333 拿到文件夹="+fileFolder );
            }

            if (!fileFolder.exists()) {
                //在这里删除以前的文件夹
                fileFolder.mkdirs();
            }

        }catch (Exception e){
            e.printStackTrace();
            Log.i(TAG, "run: mp4录制-4444，创建文件夹这里出现问题="+e.getLocalizedMessage() );
        }

        mp4Name=filedir;
        imgIndex=0;
        isNeedPoliceFlag=false;
//        String filePath;
        if (sdPath==null || sdPath.length()==0){
            mp4FilePath=Environment.getExternalStorageDirectory()+"/solar/"+filedir.substring(0,8)+"/camera/"+filedir+".mp4";
            Log.i(TAG, "run: mp4录制-5555，拿到录制文件路径="+mp4FilePath );
        }else {
            mp4FilePath=sdPath+"/solar/"+filedir.substring(0,8)+"/camera/"+filedir+".mp4";
            Log.i(TAG, "run: mp4录制-6666，拿到录制文件路径="+mp4FilePath );
        }
        mp4FilePath=new String(mp4FilePath.getBytes(StandardCharsets.UTF_8));

        try {
            if (publishStr!=null){
                myOpenGLView.startRecord(mp4FilePath,publishStr);
            }else {
                publishStr= QiNiuUtil.getRtmpUrl(isQiniuFlag,TestConfig.accessKey,TestConfig.secretKey,getContext());
//                if (publishStr!=null){
                myOpenGLView.startRecord(mp4FilePath,publishStr);
//                }
            }
            Log.i(TAG, "run: mp4录制-7777，七牛云录制="+publishStr );
        }catch (Exception e){
            e.printStackTrace();
            Log.i(TAG, "run: mp4录制-8888，录制中出现了问题="+e.getLocalizedMessage() );
        }



        nv21Flag=true;
//        Log.i(TAG, "createNewRecord: 在这里完成了一帧图片的提取的标志为="+nv21Flag );
//        Log.i("record", "run: mp4的创建 开始录制:"+mp4FilePath);
        //间隔多少时间响闹钟
        AlarmUtil.createRecord(context,-100,min);
    }



    /**
     *  搞不同id轮流来定时，看能否解决问题
     * @param id  设置id
     * @param minute 设置延时时间开启
     */
    private void createRecord(int id,int minute){
        Calendar calendar= TimeUtil.getCaledar(minute);
        Log.i(TAG, "run: mp4录制-9999,准备定时的时间="+calendar.getTimeInMillis());
//        int id=-100;
        Intent intent1=new Intent(context, AlarmReciever.class);
        intent1.putExtra("_id",id);
        intent1.putExtra("flag",false);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(context,id,intent1,0);

        AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            //大于6.0
            Log.i(TAG, "run: mp4录制-1010,添加的闹钟="+calendar.getTimeInMillis());
            alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP,calendar.getTimeInMillis(),pendingIntent);
        } else if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
            //大于4.4
            Log.i(TAG, "run: mp4录制-1212,添加的闹钟");
            alarmManager.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),pendingIntent);
        } else {
//            if (flag == 0) {	//一次性闹钟
//                alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), sender);
//            } else {			//重复闹钟
//                alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calMethod(week, calendar.getTimeInMillis()), intervalMillis, sender);
//            }
            Log.i(TAG, "run: mp4录制-1313,添加的闹钟");
            alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),  pendingIntent);
        }

    }

    private void delRecord(Date date){
        if (date==null)return;
        Log.i(TAG, "saveMp4: 保存mp4文件33333" );
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss"); // 格式化时间
        String filedir = format.format(date);

//        String filePath=Environment.getExternalStorageDirectory()+"/solar/"+filedir.substring(0,8)+"/camera/"+filedir+".mp4";
        String filePath;
        if (sdPath==null || sdPath.length()==0){
            filePath=Environment.getExternalStorageDirectory()+"/solar/"+filedir.substring(0,8)+"/camera/"+filedir+".mp4";
        }else {
            filePath=sdPath+"/solar/"+filedir.substring(0,8)+"/camera/"+filedir+".mp4";
        }

        File file=new File(filePath);
        if (file.exists() && file.isFile()){
            file.delete();
            Log.i(TAG, "saveMp4: 保存mp4文件44444" );
        }

    }


}
